/**
 * 
 */
package fr.toussna.service.impl;

import java.util.List;

import javax.jws.WebService;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import fr.toussna.dao.CategoryDAO;
import fr.toussna.dao.MemberDAO;
import fr.toussna.entity.Category;
import fr.toussna.entity.Member;
import fr.toussna.exception.ElementNotExistException;
import fr.toussna.exception.ObjectNotFoundException;
import fr.toussna.service.AccountService;
import fr.toussna.service.ArticleService;

/**
 * Cette classe est l'implémentation de l'interface de service
 * {@link AccountService}
 * 
 * @author My
 * @version 2.0
 * 
 */
@WebService(endpointInterface = "fr.toussna.service.AccountService", serviceName = "accountService")
public class AccountServiceImpl implements AccountService {

	private static final Log LOGGER = LogFactory.getLog(AccountServiceImpl.class.getName());

	// **********************************
	// * Dependances *
	// **********************************
	/**
	 * Bean pour accéder aux données. Spring IOC
	 */
	MemberDAO memberedao;

	/**
	 * Bean pour accéder aux données. Spring IOC
	 */
	CategoryDAO categorydao;

	/**
	 * Classe des service du même package
	 */
	private ArticleService articletService;

	// **********************************
	// * Methodes Hertiees *
	// **********************************

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * fr.toussna.service.AccountService#createCategory(fr.toussna.entity.Category
	 * )
	 */
	@Override
	public Category createCategory(Category category) {

		Long id = (Long) categorydao.insert(category);
		category.setId(id);
		categorydao.insertToCache(category);

		if (LOGGER.isDebugEnabled()) {
			LOGGER.info("Creating category: " + category + "\n Returned id: " + id);
		}
		return category;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see fr.toussna.service.AccountService#findCategory(long)
	 */
	@Override
	public Category findCategory(long id) throws ElementNotExistException {

		Category category = (Category) categorydao.selectCachedElement(id, Category.class.getCanonicalName());
		if (category == null) {
			try {
				category = (Category) categorydao.select(id);
			} catch (ObjectNotFoundException e) {
				LOGGER.error("Category id not found" + id, e);
				throw new ElementNotExistException(e);
			}
		}
		// Rajout des articles appartenant a cette categorie
		category.setArticles(articletService.getCategoryOfArticle(category));
		if (LOGGER.isDebugEnabled()) {
			LOGGER.info(" Getting category with id :" + id + "\n returned category: " + category + " attached articles: " + category.getArticles());
		}

		return category;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see fr.toussna.service.AccountService#findAllCategories()
	 */
	@Override
	public List<Category> findAllCategories() {

		List liste = categorydao.selectAll();

		if (LOGGER.isDebugEnabled()) {
			LOGGER.info("Getting all categories of the system: " + "\n" + liste);
		}
		return liste;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * fr.toussna.service.AccountService#deleteCategory(fr.toussna.entity.Category
	 * )
	 */
	@Override
	public void deleteCategory(Category category) {

		categorydao.delete(category);

		if (LOGGER.isDebugEnabled()) {
			LOGGER.info(" Deleting category:" + category);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * fr.toussna.service.AccountService#createMember(fr.toussna.entity.Member)
	 */
	@Override
	public Member createMember(Member member) {

		Long id = (Long) memberedao.insert(member);
		member.setId(id);
		memberedao.insertToCache(member);

		if (LOGGER.isDebugEnabled()) {
			LOGGER.info(" Creating a member: " + member + "\n returned id: " + id);
		}
		return member;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * fr.toussna.service.AccountService#deleteMember(fr.toussna.entity.Member)
	 */
	@Override
	public void deleteMember(Member member) {

		memberedao.delete(member);

		if (LOGGER.isDebugEnabled()) {
			LOGGER.info(" Deleting a member: " + member);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * fr.toussna.service.AccountService#updateMember(fr.toussna.entity.Member)
	 */
	@Override
	public void updateMember(Member member) {

		memberedao.update(member);
		memberedao.insertToCache(member);

		if (LOGGER.isDebugEnabled()) {
			LOGGER.info(" Updating a member: " + member);
		}

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see fr.toussna.service.AccountService#findMember(long)
	 */
	@Override
	public Member findMember(long id) throws ElementNotExistException {
		Member member = (Member) memberedao.selectCachedElement(id, Member.class.getCanonicalName());
		if (member == null) {
			try {
				member = (Member) memberedao.select(id);
			} catch (ObjectNotFoundException e) {
				LOGGER.error("Member id not found" + id, e);
				throw new ElementNotExistException(e);
			}
		}
		// Rajout des article de ce membre
		member.setArticles(articletService.findArticleOfMember(member));
		if (LOGGER.isDebugEnabled()) {
			LOGGER.info(" Finding a member with id : " + id + "\n returned member: " + member + "\n articles attached: " + member.getArticles());
		}
		return member;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see fr.toussna.service.AccountService#findMemberByName(java.lang.String)
	 */
	@Override
	public List<Member> findMemberByName(String name) {
		List liste = memberedao.selectByName(name);

		if (LOGGER.isDebugEnabled()) {
			LOGGER.info(" Finding members matching name:" + name + "\n returned list :" + liste);
		}
		return liste;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * fr.toussna.service.AccountService#IdentifyWebClient(fr.toussna.entity
	 * .Member)
	 */
	@Override
	public Boolean IdentifyWebClient(Member member) {
		List<Member> list = findMemberByName(member.getEmail());
		if (!list.isEmpty() && list.get(0).getPassword().equals(member.getPassword())) {
			return true;
		} else
			return false;
	}

	// **********************************
	// * Getters & Setters *
	// **********************************

	/**
	 * Used by Spring IOC
	 * 
	 * @param memberedao
	 *            Le membreDAO a setter
	 */
	public void setMemberedao(MemberDAO memberedao) {
		this.memberedao = memberedao;
	}

	/**
	 * Utilisé par Spring IOC
	 * 
	 * @param categorydao
	 *            La caegoryDAO a setter
	 */
	public void setCategorydao(CategoryDAO categorydao) {
		this.categorydao = categorydao;
	}

	/**
	 * @param articletService
	 *            Le service des articles
	 */
	public void setArticletService(ArticleService articletService) {
		this.articletService = articletService;
	}

}
